home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr13 / jed10.zip / VIDBLAST.ASM < prev   
Assembly Source File  |  1993-08-14  |  10KB  |  201 lines

  1. ;===========================================================================
  2. ;
  3. ; V I D B L A S T  -  Blast character pattern into memory, & add attributes
  4. ;
  5. ;===========================================================================
  6. ;
  7. ;     by Jeff Duntemann      25 November 1988
  8. ;
  9. ; VIDBLAST is written to be called from Turbo Pascal V4.0 or 5.0 using the
  10. ; EXTERNAL machine-code procedure convention.
  11. ;
  12. ; Declare the procedure itself as external using this declaration:
  13. ;
  14. ; PROCEDURE VidBlast(ScreenEnd,StoreEnd : ScrnPtr;
  15. ;                    ScreenX,ScreenY    : Integer;
  16. ;                    ULX,ULY            : Integer;
  17. ;                    Width,Height       : Integer;
  18. ;                    Attribute          : Byte;
  19. ;                    DeadLines          : Integer);
  20. ;           EXTERNAL;
  21. ;
  22. ; What we have here is a means of moving a rectangular region of a text
  23. ; screen (either the visible screen or a screen stored on the heap) from
  24. ; the screen array to a storage array.  It is the text analog of a BITBLT
  25. ; (BIT BLock Transfer.)  It is an essential component of any windowing or
  26. ; menuing system that expects to update the display faster than the eyes
  27. ; can follow.
  28. ;
  29. ; It works like this:  ScreenEnd and StoreEnd are the two pointers pointing
  30. ; to the screen array and the storage array, respectively.  If the destination
  31. ; pointer is NIL, VidBlast returns without taking any action.  ScreenX and
  32. ; ScreenY are the dimensions of the screen in use.  ULX and ULY are the
  33. ; coordinates of the upper left hand corner of the rectangular region to be
  34. ; written to on the destination screen.  Width and Height are the dimensions
  35. ; of the region to be written to on the destination screen.
  36. ;
  37. ; During the blast itself, the attribute byte passed in the Attribute
  38. ; parameter is written to the screen along with the character information
  39. ; pointed to by the source pointer.  In effect, this means we do a byte-sized
  40. ; read from the source character data, but a word-sized write to the screen.
  41. ;
  42. ;
  43. ; There is a critical difference between a screen array and a storage array.
  44. ; A screen array has an implied structure of rows and columns, dictated by
  45. ; the ScreenX and ScreenY parameters.  A rectangular region within such an
  46. ; array is not one contiguous block of elements, but rather a number of
  47. ; blocks of elements separated by some quantity of storage not included in
  48. ; the block transfer.  Additionally, the rectangular region begins at some
  49. ; offset from the beginning of the screen array.  A storage buffer, by
  50. ; contrast, is a simple contiguous array of character/attribute pairs without
  51. ; any consideration for the row/column structure of a visible screen.  We
  52. ; do it this way for the utmost speed and most efficient use of memory.
  53. ;
  54. ; Allocation of both screen and storage arrays, of course, is the
  55. ; responsibility of the calling logic.  HINT: Use GetMem and FreeMem
  56. ; rather than New and Dispose.
  57. ;
  58. ;
  59. ; To reassemble/relink WORDBLT:
  60. ;
  61. ; Assemble this file with MASM or TASM:  "C>MASM VIDBLAST;"
  62. ; (The semicolon is unnecessary with TASM.)
  63. ;
  64. ;========================
  65. ;
  66. ; STACK PROTOCOL
  67. ;
  68. ; This creature puts lots of things on the stack.  Study closely:
  69. ;
  70.  
  71. ONSTACK STRUC
  72. OLDBP   DW ?    ;Caller's BP value saved on the stack
  73. RETADDR DD ?    ;Full 32-bit return address.  (This is a FAR proc!)
  74. DEADLNS DW ?    ;Number of lines of dead space to insert between blasted lines
  75. ATTR    DW ?    ;Attribute to be added to blasted pattern
  76. WHEIGHT DW ?    ;HEIGHT OF WINDOW TO BE MOVED
  77. WWIDTH  DW ?    ;WIDTH OF WINDOW TO BE MOVED
  78. ULY     DW ?    ;Y COORDINATE OF UPPER LEFT CORNER OF WINDOW
  79. ULX     DW ?    ;X COORDINATE OF UPPER LEFT CORNER OF WINDOW
  80. YSIZE   DW ?    ;GENNED MAX Y DIMENSION OF CURRENT VISIBLE SCREEN
  81. XSIZE   DW ?    ;GENNED MAX X DIMENSION OF CURRENT VISIBLE SCREEN
  82. STORE   DD ?    ;32-BIT POINTER TO STORE BUFFER
  83. SCREEN  DD ?    ;32-BIT POINTER TO SCREEN BUFFER
  84. ENDMRK  DB ?    ;DUMMY FIELD FOR SIZE CALCULATION PURPOSES
  85. ONSTACK ENDS
  86.  
  87.  
  88. CODE    SEGMENT PUBLIC
  89.         ASSUME  CS:CODE
  90.         PUBLIC  VIDBLAST
  91.  
  92. VIDBLAST PROC    FAR
  93.          PUSH    BP                      ;SAVE CALLER'S BP VALUE
  94.          MOV     BP,SP                   ;SP BECOMES NEW VALUE OF BP
  95.          PUSH    DS                      ;SAVE CALLER'S DS VALUE
  96.  
  97. ;-------------------------------------------------------------------------
  98. ; The increment between window lines must be calculated and stored in DX.
  99. ; This includes adding additional instances of the increment for "dead
  100. ; space" to avoid lines between forms, things like that.
  101. ;-------------------------------------------------------------------------
  102.  
  103.         MOV     DX,[BP].XSIZE
  104.         SUB     DX,[BP].WWIDTH          ;INCREMENT IS SCREEN WIDTH MINUS
  105.                                         ; WINDOW WIDTH
  106.         SHL     DX,1                    ;INCREMENT IS IN WORDS.  MUST
  107.                                         ; CONVERT TO BYTES FOR USE; HERE
  108.                                         ; WE MULTIPLY IT BY TWO BY
  109.                                         ; SHIFTING LEFT ONE BIT
  110.         MOV     CX,[BP].DeadLns         ;Put deadspace line count in CX
  111.         CMP     CX,0                    ;Is there any dead space needed?
  112.         JE      Inset                   ;If not, go calculate the inset
  113.  
  114.         MOV     BX,[BP].XSIZE           ;Mov screen width into BX
  115.         SHL     BX,1                    ;Multiply by two for attributes
  116. AddDed: ADD     DX,BX                   ;Add a screen width to increment
  117.         LOOP    AddDed                  ;Dec CX & loop backn if CX <> 0
  118.  
  119.  
  120. ;-------------------------------------------------------------------------
  121. ;  HERE WE CALCULATE THE INSET FROM THE START OF THE VISIBLE
  122. ;    SCREEN BUFFER TO THE FIRST BYTE OF THE WINDOW TO BE BLITTED
  123. ;-------------------------------------------------------------------------
  124.  
  125. Inset:  PUSH    DX                      ;Save increment; MUL trashes DX
  126.         MOV     CX,[BP].XSIZE           ;SCREEN MAX X DIMENSION IN CX
  127.         MOV     BX,[BP].ULX             ;UL CORNER X DIMENSION IN BX
  128.         MOV     AX,[BP].ULY             ;UL CORNER Y DIMENSION IN AX
  129.         SUB     BX,1                    ;CORRECT FOR ORIGIN AT 1 NOT 0
  130.         SUB     AX,1                    ;CORRECT FOR ORIGIN AT 1 NOT 0
  131.         MUL     CX                      ;MULTIPLY SCREEN WIDTH BY UL Y
  132.         ADD     AX,BX                   ; AND ADD INDENT FROM LEFT MARGIN
  133.         MOV     CX,AX
  134.         SHL     CX,1
  135.  
  136.  
  137. ;-------------------------------------------------------------------------
  138. ;  NEXT WE HAVE TO FILL THE SOURCE AND DESTINATION SEGMENT AND OFFSET
  139. ;    REGISTERS, DEPENDING ON WHICH WAY DATA WILL BE FLOWING.  DS:SI IS
  140. ;    ALWAYS THE SOURCE ADDRESS, AND ES:DI IS ALWAYS THE DESTINATION
  141. ;    ADDRESS.  TOWARD DETERMINES WHETHER DATA WILL BE FLOWING TOWARD THE
  142. ;    SCREEN BUFFER OR TOWARD THE STORAGE BUFFER.  MUCH OF THIS CODE IS
  143. ;    CHECKING TO SEE IF EITHER POINTER WAS SET TO NIL, I.E. BOTH WORDS
  144. ;    SET TO ZERO.  IF EITHER POINTER WAS PASSED AS NIL, WORDBLT RETURNS
  145. ;    WITHOUT TAKING FURTHER ACTION.
  146. ;-------------------------------------------------------------------------
  147.  
  148.         LES     DI,[BP].SCREEN          ;SCREEN IS DESTINATION: ES:DI
  149.         LDS     SI,[BP].STORE           ;STORAGE BUFFER IS SOURCE: DS:SI
  150.  
  151.         MOV     AX,ES                   ;CAN'T DO A CMP ON A SEGMENT REG.
  152.         CMP     AX,0                    ;A NIL POINTER IS A SEGMENT AND
  153.         JNE     AddIn                   ; OFFSET BOTH SET TO 0
  154.         CMP     DI,0                    ;RETURN WITHOUT ACTING IF BOTH
  155.         JE      GOHOME                  ; ARE SET TO 0
  156.  
  157. AddIn:  ADD     DI,CX                   ;SCREEN END MUST ADD INSET VALUE
  158.                                         ; TO OFFSET PORTION OF POINTER
  159.         POP     DX                      ;Restore saved increment to DX
  160.  
  161. ;-------------------------------------------------------------------------
  162. ;  THE POINTERS ARE NOW READY FOR WORK.  NOW WE SET UP FOR THE LOOPS.
  163. ;    THE DIRECTION FLAG MUST BE SET FOR AUTOINCREMENT DURING LOOPS.
  164. ;-------------------------------------------------------------------------
  165.  
  166.         MOV     AX,[BP].WHEIGHT         ;HEIGHT IS COUNT OF LINE MOVES
  167.         MOV     BX,[BP].Attr            ;Move attribute byte into BX
  168.         XCHG    BH,BL                   ;Put attribute info into high byte
  169.  
  170. ;-------------------------------------------------------------------------
  171. ;  DOLINE IS THE LABEL FOR THE OUTER LOOP.  THIS LOOP PERFORMS HEIGHT
  172. ;    STOSW OPS WHICH EACH MOVE WIDTH WORDS FROM SOURCE TO DESTINATION
  173. ;-------------------------------------------------------------------------
  174.  
  175. DOLINE: MOV     CX,[BP].WWIDTH          ;COUNT VALUE FOR INNER LOOP IS WIDTH
  176.  
  177. DoChar: MOV     BL,[SI]                 ;Bring source byte into BL
  178.         MOV     ES:[DI],BX              ;Move WORD QUANTITY to ES:DI
  179.         INC     SI                      ;Bump SI to next byte
  180.         INC     DI                      ;Bump DI *by two* to next word
  181.         INC     DI
  182.         LOOP    DoChar                  ;Repeat inner loop until CX is zero
  183.  
  184.         ADD     DI,DX                   ;ADD DESTINATION INCREMENT TO DI
  185.         DEC     AX                      ;AX IS HEIGHT; I.E. OUTER LOOP COUNTER
  186.         JNZ     DOLINE                  ;AND LOOP UNTIL AX IS ZERO
  187.  
  188. ;-------------------------------------------------------------------------
  189. ;  WHEN THE OUTER LOOP IS FINISHED, THE WORK IS DONE.  RESTORE REGISTERS
  190. ;    AND GO HOME.
  191. ;-------------------------------------------------------------------------
  192.  
  193. GOHOME: POP     DS                      ;RESTORE CALLER'S DS
  194.         MOV     SP,BP                   ;RESTORE PRIOR STACK POINTER & BP
  195.         POP     BP                      ; IN CONVENTIONAL RETURN
  196.         RET     ENDMRK-RETADDR-4
  197.  
  198. VIDBLAST ENDP
  199. CODE     ENDS
  200.          END
  201.